package com.atguigu.gulimall.product.service.impl;

import com.atguigu.common.constant.ProductConstant;
import com.atguigu.gulimall.product.dao.AttrAttrgroupRelationDao;
import com.atguigu.gulimall.product.dao.AttrGroupDao;
import com.atguigu.gulimall.product.dao.CategoryDao;
import com.atguigu.gulimall.product.entity.AttrAttrgroupRelationEntity;
import com.atguigu.gulimall.product.entity.AttrGroupEntity;
import com.atguigu.gulimall.product.entity.CategoryEntity;
import com.atguigu.gulimall.product.service.CategoryService;
import com.atguigu.gulimall.product.vo.AttrGroupRelationVO;
import com.atguigu.gulimall.product.vo.AttrRespVO;
import com.atguigu.gulimall.product.vo.AttrVO;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.atguigu.common.utils.PageUtils;
import com.atguigu.common.utils.Query;

import com.atguigu.gulimall.product.dao.AttrDao;
import com.atguigu.gulimall.product.entity.AttrEntity;
import com.atguigu.gulimall.product.service.AttrService;
import org.springframework.transaction.annotation.Transactional;


@Service("attrService")
public class AttrServiceImpl extends ServiceImpl<AttrDao, AttrEntity> implements AttrService {

    @Autowired
    private AttrAttrgroupRelationDao relationDao;

    @Autowired
    private AttrGroupDao groupDao;

    @Autowired
    private CategoryDao categoryDao;

    @Autowired
    private CategoryService categoryService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<AttrEntity> page = this.page(
                new Query<AttrEntity>().getPage(params),
                new QueryWrapper<AttrEntity>()
        );

        return new PageUtils(page);
    }

    @Transactional
    @Override
    public void saveAttr(AttrVO attr) {
        AttrEntity attrEntity = new AttrEntity();
        BeanUtils.copyProperties(attr, attrEntity);
        //1、保存基本数据
        this.save(attrEntity);
        //2、保存关联关系
        if (ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode() == attr.getAttrType() &&
                attr.getAttrGroupId() != null) {
            AttrAttrgroupRelationEntity relationEntity = new AttrAttrgroupRelationEntity();
            relationEntity.setAttrId(attrEntity.getAttrId());
            relationEntity.setAttrGroupId(attr.getAttrGroupId());
            relationEntity.setAttrSort(0);
            relationDao.insert(relationEntity);
        }
    }

    @Override
    public PageUtils queryBaseAttrPage(Map<String, Object> params, Long catelogId, String attrType) {
        QueryWrapper<AttrEntity> queryWrapper = new QueryWrapper<>();

        //类别id
        if (catelogId != 0) {
            queryWrapper.eq("catelog_id", catelogId);
        }
        if (StringUtils.isNotBlank(attrType)) {
            //0-销售属性，1-基本属性
            //sale attrType=0
            //base attrType=1
            Integer realAttrType = attrType.equalsIgnoreCase(ProductConstant.AttrEnum.ATTR_TYPE_SALE.getName()) ?
                    ProductConstant.AttrEnum.ATTR_TYPE_SALE.getCode() :
                    ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode();
            queryWrapper.eq("attr_type", realAttrType);
        }

        String key = params.get("key") != null ? (String) params.get("key") : "";
        if (StringUtils.isNotBlank(key)) {
            //attr_id attr_name
            queryWrapper.and(queryWrapper2 -> {
                queryWrapper2
                        .like("attr_name", key);
                //attr_id
                //如果是数字格式 ^\d{n,}$
                boolean isMatch = Pattern.matches("^\\d{1,}$", key);
                if (isMatch) {
                    Long attrId = Long.parseLong(key);
                    queryWrapper2.or().eq("attr_id", attrId);//属性id
                }
            });
        }

        IPage<AttrEntity> page = this.page(
                new Query<AttrEntity>().getPage(params),
                queryWrapper
        );
        PageUtils pageUtils = new PageUtils(page);

        List<AttrEntity> records = page.getRecords();
        List<AttrRespVO> respVOList = records.stream().map(attrEntity -> {
            AttrRespVO respVO = new AttrRespVO();
            BeanUtils.copyProperties(attrEntity, respVO);
            //1、设置分类和分组的名字
            CategoryEntity categoryEntity = categoryDao.selectById(respVO.getCatelogId());
            respVO.setCatelogName(categoryEntity.getName());

            //base(基本属性)才又属性分组信息
            if (ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode() == respVO.getAttrType()) {
                AttrAttrgroupRelationEntity relationEntity =
                        relationDao.selectOne(new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_id", respVO.getAttrId()));
                if (relationEntity != null) {
                    Long attrGroupId = relationEntity.getAttrGroupId();
                    AttrGroupEntity attrGroupEntity = groupDao.selectById(attrGroupId);
                    respVO.setGroupName(attrGroupEntity.getAttrGroupName());
                }
            }
            return respVO;
        }).collect(Collectors.toList());
        pageUtils.setList(respVOList);
        return pageUtils;
    }

    @Override
    public AttrRespVO getAttrInfo(Long attrId) {
        AttrRespVO respVO = new AttrRespVO();
        AttrEntity attrEntity = this.baseMapper.selectById(attrId);
        BeanUtils.copyProperties(attrEntity, respVO);

        //1、attrGroupId
        if (ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode() == attrEntity.getAttrType()) {
            AttrAttrgroupRelationEntity relationEntity = relationDao.selectOne(new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_id", respVO.getAttrId()));
            if (relationEntity != null) {
                Long attrGroupId = relationEntity.getAttrGroupId();
                AttrGroupEntity attrGroupEntity = groupDao.selectById(attrGroupId);
                if (attrGroupEntity != null) {
                    respVO.setGroupName(attrGroupEntity.getAttrGroupName());
                    respVO.setAttrGroupId(attrGroupId);
                }
            }
        }

        //2、catelogPath
        Long[] catelogPath = categoryService.findCatelogPath(attrEntity.getCatelogId());
        respVO.setCatelogPath(catelogPath);
        CategoryEntity categoryEntity = categoryDao.selectById(attrEntity.getCatelogId());
        if (categoryEntity != null) {
            respVO.setCatelogName(categoryEntity.getName());
        }

        return respVO;
    }

    @Override
    public void updateAttr(AttrVO attr) {
        //1、修改基本数据
        AttrEntity attrEntity = new AttrEntity();
        BeanUtils.copyProperties(attr, attrEntity);
        this.updateById(attrEntity);
        //2、修改分组关联
        //update pms_attr_attrgroup_relation set attr_group_id=? where attr_id=?
        if (ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode() == attrEntity.getAttrType() &&
                attr.getAttrGroupId() != null) {
            AttrAttrgroupRelationEntity relationEntity = new AttrAttrgroupRelationEntity();
            relationEntity.setAttrGroupId(attr.getAttrGroupId());
            relationEntity.setAttrId(attr.getAttrId());
            Integer count = relationDao.selectCount(new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_id", attr.getAttrId()));
            if (count > 0) {
                relationDao.update(relationEntity, new UpdateWrapper<AttrAttrgroupRelationEntity>().eq("attr_id", attr.getAttrId()));
            } else {
                relationEntity.setAttrSort(0);
                relationDao.insert(relationEntity);
            }
        }
    }

    /**
     * 根据分组id查找关联的所有基本(base)属性
     * attr_group_id ---> attr_attrgroup_relation:attr_id ---> attr:attr信息
     *
     * @param attrgroupId
     * @return
     */
    @Override
    public List<AttrEntity> getRelationAttr(Long attrgroupId) {
        List<AttrEntity> attrEntities = new ArrayList<>();
        List<AttrAttrgroupRelationEntity> relationEntities =
                relationDao.selectList(new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_group_id", attrgroupId));
        List<Long> attrIds = relationEntities.stream().map(AttrAttrgroupRelationEntity::getAttrId).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(attrIds)) {
            attrEntities = this.listByIds(attrIds);
        }
        return attrEntities;
    }

    @Transactional
    @Override
    public void deleteRelation(List<AttrGroupRelationVO> voList) {
//        voList.forEach(attrGroupRelationVO ->
//                relationDao.delete(
//                        new QueryWrapper<AttrAttrgroupRelationEntity>()
//                                .eq("attr_id", attrGroupRelationVO.getAttrId())
//                                .eq("attr_group_id", attrGroupRelationVO.getAttrGroupId())
//                )
//        );
        List<AttrAttrgroupRelationEntity> relationEntities = voList.stream().map(attrGroupRelationVO -> {
            AttrAttrgroupRelationEntity entity = new AttrAttrgroupRelationEntity();
            entity.setAttrId(attrGroupRelationVO.getAttrId());
            entity.setAttrGroupId(attrGroupRelationVO.getAttrGroupId());
            return entity;
        }).collect(Collectors.toList());
        relationDao.deleteBatchRelation(relationEntities);
    }

    /**
     * 获取属性分组没有关联的其他属性
     *
     * @param params
     * @param attrgroupId
     * @return
     */
    @Override
    public PageUtils getNoRelationAttr(Map<String, Object> params, Long attrgroupId) {
        //当前分类的所有属性 ---> 这些属性中没有关联属性分组的
        //1、当前分组只能关联自己所属的分类里面的所有属性
        AttrGroupEntity attrGroupEntity = groupDao.selectById(attrgroupId);
        Long catelogId = attrGroupEntity.getCatelogId();
        //2、当前分组只能关联别的分组没有引用的属性
        //2.1、当前分类下的其他分组
        List<AttrGroupEntity> group = groupDao.selectList(
                new QueryWrapper<AttrGroupEntity>()
                        .eq("catelog_id", catelogId));
//                        .ne("attr_group_id", attrgroupId));
        List<Long> attrGroupIds = group.stream().map(AttrGroupEntity::getAttrGroupId).collect(Collectors.toList());
        //2.2、这些分组关联的属性
        List<AttrAttrgroupRelationEntity> otherRelationEntities = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(attrGroupIds)) {
            otherRelationEntities = relationDao.selectList(
                    new QueryWrapper<AttrAttrgroupRelationEntity>().in("attr_group_id", attrGroupIds));
        }
        List<Long> otherAttrIds = otherRelationEntities.stream().map(AttrAttrgroupRelationEntity::getAttrId).collect(Collectors.toList());
        //2.3、当前分类的所有属性中移除这些属性
        QueryWrapper<AttrEntity> queryWrapper = new QueryWrapper<AttrEntity>()
                .eq("catelog_id", catelogId)
                .eq("attr_type", ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode());
        if (CollectionUtils.isNotEmpty(otherAttrIds)) {
            queryWrapper.notIn("attr_id", otherAttrIds);
        }
        String key = params.get("key") != null ? (String) params.get("key") : "";
        if (StringUtils.isNotBlank(key)) {
            queryWrapper.and(queryWrapper2 -> {
                queryWrapper2.like("attr_name", key);
                //attr_id
                //如果是数字格式 ^\d{n,}$
                boolean isMatch = Pattern.matches("^\\d{1,}$", key);
                if (isMatch) {
                    Long attrId = Long.parseLong(key);
                    queryWrapper2.or().eq("attr_id", attrId);//属性id
                }
            });
        }

        IPage<AttrEntity> page = this.page(
                new Query<AttrEntity>().getPage(params),
                queryWrapper
        );
        return new PageUtils(page);
    }

    @Override
    public List<Long> selectSearchAttrIds(List<Long> attrIds) {
        //select attr_id from pms_attr where attr_id in (?) and search_type = 1
        return this.baseMapper.selectSearchAttrIds(attrIds);
    }
}